import Admonition from "@theme/Admonition";
import TabItem from "@theme/TabItem";
import Tabs from "@theme/Tabs";

import ComponentConfiguration from "@site/src/pages/components-explorer/_components/ComponentConfiguration";
import ComponentHeader from "@site/src/pages/components-explorer/_components/ComponentHeader";
import ObjectDetector from "@site/src/pages/components-explorer/_domains/object_detector/index.mdx";
import ObjectDetectorLabels from "@site/src/pages/components-explorer/_domains/object_detector/labels.mdx";
import ObjectDetectorMask from "@site/src/pages/components-explorer/_domains/object_detector/mask.mdx";
import ObjectDetectorZones from "@site/src/pages/components-explorer/_domains/object_detector/zones.mdx";

import ComponentMetadata from "./_meta";
import config from "./config.json";

<ComponentHeader meta={ComponentMetadata} />

Darknet is a state-of-the-art object detector that uses the YOLO (You Only Look Once) framework.
It is built on a singel-stage algorithm to achieve both speed and accuracy.

YOLOv7 is currently the most accurate and fastest model and has hardware acceleration support on both GPUs and CPUs.

If CUDA is available on your system, `darknet` will run on your GPU.

:::note

`darknet` component uses the official [Darknet](https://github.com/AlexeyAB/darknet) implementation when running on a GPU.
When running on a CPU, it uses OpenCV's implementation of Darknet.

:::

:::info

YOLOv7 is the default model used by `darknet` in all images.

:::

## Configuration

<details>
  <summary>Configuration example</summary>

```yaml
darknet:
  object_detector:
    cameras:
      viseron_camera1:
        fps: 1
        scan_on_motion_only: true
        log_all_objects: false
        labels:
          - label: dog
            confidence: 0.7
            trigger_recorder: false
          - label: cat
            confidence: 0.8
        zones:
          - name: zone1
            coordinates:
              - x: 0
                y: 500
              - x: 1920
                y: 500
              - x: 1920
                y: 1080
              - x: 0
                y: 1080
            labels:
              - label: person
                confidence: 0.8
                trigger_recorder: true
        mask:
          - coordinates:
              - x: 400
                y: 200
              - x: 1000
                y: 200
              - x: 1000
                y: 750
              - x: 400
                y: 750
```

</details>

<ComponentConfiguration meta={ComponentMetadata} config={config} />

## Object detector

<ObjectDetector />

### Labels

<ObjectDetectorLabels labelPath="/detectors/models/darknet/coco.names" />

### Zones

<ObjectDetectorZones meta={ComponentMetadata} />

### Mask

<ObjectDetectorMask meta={ComponentMetadata} />

### Pre-trained models

The included models are placed inside the `/detectors/models/darknet` folder.

<details>
<summary>Included models:</summary>

- `yolov3-tiny.weights`
- `yolov3.weights`
- `yolov4-tiny.weights`
- `yolov4.weights`
- `yolov7-tiny.weights`
- `yolov7.weights`
- `yolov7x.weights`

:::tip

This [GitHub issue](https://github.com/AlexeyAB/darknet/issues/7087#issue-758524970) explains the models quite well.

To make an educated guess of what model to use, you can reference [this image.](https://user-images.githubusercontent.com/4096485/101356322-f1f5a180-38a8-11eb-9907-4fe4f188d887.png)<br></br>
It will help you find the perfect trade-off between accuracy and latency.

:::

:::warning

The image `roflcoopter/rpi3-viseron` only includes the `yolov7-tiny.weights` model.

:::

</details>

<Admonition type="tip">
The containers also has <code>*-tiny.weights</code> model included in the image.
The tiny-models can be used to reduce CPU and RAM usage.
If you want to swap to a tiny-model you can change these configuration options:

<Tabs>
<TabItem value="yolov7" label="YOLOv7" default>

```yaml
darknet:
  object_detector:
    model_path: /detectors/models/darknet/yolov7-tiny.weights
    model_config: /detectors/models/darknet/yolov7-tiny.cfg
```

</TabItem>
<TabItem value="yolov4" label="YOLOv4" default>

```yaml
darknet:
  object_detector:
    model_path: /detectors/models/darknet/yolov4-tiny.weights
    model_config: /detectors/models/darknet/yolov4-tiny.cfg
```

</TabItem>
<TabItem value="yolov3" label="YOLOv3">

```yaml
darknet:
  object_detector:
    model_path: /detectors/models/darknet/yolov3-tiny.weights
    model_config: /detectors/models/darknet/yolov3-tiny.cfg
```

</TabItem>
</Tabs>

<Admonition type="note">
  The tiny-models have <b>significantly</b> worse accuracy than their larger
  counterparts.
</Admonition>

</Admonition>

### Hardware acceleration

Hardware accelerated object detection is supported on NVIDIA GPUs and Intel CPUs with integrated GPUs.
If you dont have a GPU available, `darknet` will run on the CPU.

#### NVIDIA GPUs

If your system supports CUDA it is recommended to use the `roflcoopter/amd64-cuda-viseron` image.
It will automatically use CUDA for object detection.

:::info
When running on CUDA, native [Darknet](https://github.com/AlexeyAB/darknet) is used.
:::

:::tip
If you want to force `darknet` to run on OpenCL even if you have an NVIDIA GPU you can set these config options:

```yaml
darknet:
  object_detector:
    dnn_backend: openvino
    dnn_target: opencl
```

:::

#### Intel CPUs with integrated GPUs

If you are running on an Intel CPU with integrated GPU, you can use the `roflcoopter/amd64-viseron` image.
It will automatically use OpenCV with OpenVINO and OpenCL for object detection.

The `dnn_backend` and `dnn_target` controls how the model runs.

:::info
When not running on CUDA, OpenCVs implementation of Darknet is used.
:::
